# coding=utf-8

import os
import time
import json

from django.conf.urls import url
from django.http import JsonResponse

from apps.mgr.share import app_logger, danger_logger
from apps.admin.handlers import (absorbed)
from project.settings import USER_LEVEL
from apps.admin.handlers import (login)
from lib.common import LOG_ACTION_CHINESE

Error_Not_Login = JsonResponse({
    'retcode': 302,
    'msg': '未登录',
    'redirect': '/mgr/login/login.html',
})
Error_UserType = JsonResponse({
    'retcode': 1,
    'msg': '请以正确权限的帐号登录',
    'redirect': '/mgr/login/login.html',
})

# A simple security checking, more preventions are needed in risky APIs: modification, deletion, insert etc.
# user type to http referer string
HTTP_REFERER_DICT = {
    1: '/mgr/',
    1001: '/datainputer/',
    1002: '/ragent/',
    1003: '/custom/',
    1004: '/operator/',
    10010: '/temporary/',
    10011: '/shipper/'
}


def CheckUserIsAdminForApiCaller(request, *args, **kwargs):
    # if not request.user.is_authenticated():
    #     return Error_Not_Login
    execStartTime = time.time()

    if 'ut' not in request.session:
        return Error_Not_Login

    if request.session['ut'] not in (USER_LEVEL.LEVEL_SUPERUSER,
                                     USER_LEVEL.LEVEL_YUNWEI,
                                     USER_LEVEL.LEVEL_OPERATOR,
                                     USER_LEVEL.LEVEL_ENDORSEMENT,
                                     USER_LEVEL.LEVEL_PLATINUM,
                                     USER_LEVEL.LEVEL_SHENG,
                                     USER_LEVEL.LEVEL_SHI,
                                     USER_LEVEL.LEVEL_QU,
                                     USER_LEVEL.LEVEL_CLASSMASTER):
        return Error_UserType

    # referer = request.META.get('HTTP_REFERER')
    # if referer and (HTTP_REFERER_DICT[request.session['ut']] in referer):
    #     pass
    # else:
    #     return Error_UserType

    realCall = kwargs.pop('_viewFunc')

    ret = realCall(request, *args, **kwargs)

    if request.method in ('POST', 'DELETE', 'PUT'):
        url_path = request.path
        action_dict = LOG_ACTION_CHINESE.get(url_path.split('/')[3] if len(url_path.split('/')) > 4 else None)
        if not action_dict:
            danger_logger.info('!! 通知开发人员添加 [{method}] user_id : {user}, path : {path}, data: {data}'.format(
                method=request.method,
                user=request.session.get('_auth_user_id'),
                path=url_path,
                data=json.dumps(request.param_dict)))
        else:
            if request.method == 'DELETE':
                danger_logger.info('用户id {user} ，操作 {name} 模块，使用 删除 动作。路径 {path} ， 数据 {data} 。'.format(
                    user=request.session.get('_auth_user_id'), name=action_dict['name'],
                    path=url_path, data=json.dumps(request.param_dict)
                ))
            else:
                danger_logger.info('用户id {user} ，操作 {name} 模块，使用 {action} 动作。路径 {path} ， 数据 {data} 。'.format(
                    user=request.session.get('_auth_user_id'), name=action_dict['name'],
                    action=action_dict.get(request.param_dict.get('action'), '未知'),
                    path=url_path, data=json.dumps(request.param_dict)
                ))

    execEndTime = time.time()
    # 所有大于100ms的操作，产生日志告警
    opTime = execEndTime - execStartTime
    if opTime > 0.1:
        app_logger.warning('!! op takes %s seconds : function:%s %s  ' % (opTime, request.method, request.path))

    return ret


urlpatterns_api = []


def addPreCheck(urlpatterns, checkFunC):
    for pattern in urlpatterns:
        urlRegx = pattern[0]
        if type(urlRegx) != list:
            urlRegList = [urlRegx]
        else:
            urlRegList = urlRegx

        viewFunc = pattern[1]
        if len(pattern) == 2:
            for one in urlRegList:
                urlpatterns_api.append(url(one, checkFunC, {'_viewFunc': viewFunc}))

        elif len(pattern) == 3:
            otherPara = pattern[2]
            otherPara['_viewFunc'] = viewFunc
            for one in urlRegList:
                urlpatterns_api.append(url(one, checkFunC, otherPara))
        else:
            # print '!!unsupported url format : %s' % pattern
            os._exit(3)


urlpatterns_api_agrs = [
    (r'absorbed/$', absorbed.handler.dispatch),
]

addPreCheck(urlpatterns_api_agrs, CheckUserIsAdminForApiCaller)


urlpatterns = [
    url(r'^login$', login.handler.loginreq),

] + urlpatterns_api
